package com.xwq.xwqrpc;


import com.xwq.xwqrpc.config.RpcConfig;
import com.xwq.xwqrpc.constant.RpcConstant;
import com.xwq.xwqrpc.utils.ConfigUtils;
import lombok.extern.slf4j.Slf4j;

/**
 * RPC 框架应用
 * 相当于 holder，存放了项目全局用到的变量。双检锁单例模式实现
 */
@Slf4j
public class RpcApplication {

    private static volatile RpcConfig rpcConfig;

    /**
     * 框架初始化，支持传入自定义配置
     *方式1：显式初始化（用户主动传入配置）
     * @param newRpcConfig
     */
    public static void init(RpcConfig newRpcConfig) {
        rpcConfig = newRpcConfig;
        log.info("rpc init, config = {}", newRpcConfig.toString());
    }

    /**
     * 初始化
     * 方式2：隐式初始化（从配置文件加载）
     */
    public static void init() {
        RpcConfig newRpcConfig;
        try {
            // 尝试加载配置
            newRpcConfig = ConfigUtils.loadConfig(RpcConfig.class, RpcConstant.DEFAULT_CONFIG_PREFIX);
        } catch (Exception e) {
            // 加载失败时使用默认配置
            newRpcConfig = new RpcConfig();
        }
        init(newRpcConfig); // 委托给显式初始化
    }

    /**
     * 获取配置
     * 线程安全：通过 volatile + synchronized 确保多线程环境下的单例。
     * 性能优化：双检锁减少同步开销。
     * @return
     */
    public static RpcConfig getRpcConfig() {
        if (rpcConfig == null) {                // 第一次检查（避免不必要的同步）
            synchronized (RpcConfig.class) {    // 加锁
                if (rpcConfig == null) {        // 第二次检查（防止重复初始化）
                    init();                    // 懒加载
                }
            }
        }
        return rpcConfig;
    }
}
